#ifndef IMAGEPROCESSOR_H
#define IMAGEPROCESSOR_H

#include <QObject>
#include <QImage>
#include <QElapsedTimer>
#include <QThreadPool>
#include <opencv2/core/mat.hpp>
#include <opencv2/core/mat.hpp>
#include <QtConcurrent>
#include "camera.h"
#include "logger.h"
#include "preprocessor.h"
#include "imageprovider.h"
#include "camerausb.h"
#include "source/autorunprocess.h"
#include "source/cameraeth0.h"
#include <opencv2/features2d.hpp>
#include "AutoPropertyHelper.h"
#include "quicktool.h"
#include "autoSettinghelp.h"

class ImageProcessor : public QObject {
    Q_OBJECT
    Q_ENUMS(MeauName)
    Q_ENUMS(ProcessingMode)
    Q_ENUMS(CaptureImgMode)
    Q_PROPERTY(int multithreading READ multithreading NOTIFY multithreadingChange)
    Q_PROPERTY(QVariantMap detectStepInfo READ detectStepInfo NOTIFY detectStepInfoChange)
    Q_PROPERTY(QVariantMap detectStepTime READ detectStepTime NOTIFY detectStepTimeChange)
    Q_PROPERTY(QVariantMap displayimageInfo READ displayimageInfo NOTIFY displayimageInfoChanged)
    Q_PROPERTY(float currentFrameRate READ currentFrameRate NOTIFY currentFrameRateChanged)
    Q_PROPERTY(ImageProcessor::ProcessingAbortMode currentAbortMode READ getCurrentAbortMode WRITE setAbortMode)
    Q_PROPERTY(ImageProcessor::Status totalStauts READ totalStauts  NOTIFY statusChanged)
    Q_PROPERTY(ImageProcessor::CaptureImgMode captureImgMode READ captureImgMode WRITE setcaptureImgMode NOTIFY captureImgModeChange)
    Q_PROPERTY(MeauName selectedStep READ selectedStep WRITE setSelectedStep NOTIFY selectedStepChange)
    // Q_PROPERTY(int maxFrameRate READ maxFrameRate WRITE setmaxFrameRate NOTIFY maxFrameRateChange)
    Q_PROPERTY(int imgDisplayDelay READ imgDisplayDelay NOTIFY imgDisplayDelayChange)
    Q_PROPERTY(bool detectIsOk READ detectIsOk NOTIFY detectIsOkChanged)
    Q_PROPERTY(QString detectDetail READ detectDetail NOTIFY detectDetailChanged)
    Q_PROPERTY(QString ngResonDetail READ NgResonDetail NOTIFY NgResonDetailChanged)

    Q_PROPERTY(int photographyDelay READ photographyDelay WRITE setphotographyDelay NOTIFY photographyDelayChanged)


public:
    static ImageProcessor& getInstance(ImageProvider* imageProvider = nullptr) {
        static ImageProcessor instance(imageProvider);
        return instance;
    }

    enum MeauName {
        MeauBase, //0
        MeauCamera, //1
        MeauPreProcess,
        MeauAi,
        MeauCv,
        MeauPCcore, //5
        MeauIO, //6
        //MeauLight,
        MeauSummary,
        MeauAbout, //9
        MeauDetect, //10
        MeauAutoDetect, //11
    };

    enum Status {
        Running,
        Stop,
        Initializing,
        Idle,
        Error
    };

    enum ProcessingAbortMode {
        FullProcess,
        OnlyCaptured,
        OnlyPreProcess,
        OnlyDetect,
        OnlyCV,
        OnlyPCcore,
    };
    Q_ENUM(ProcessingAbortMode)

    enum CaptureImgMode {
        RateTriggered, //0
        IOTriggered,  // 1
        SingleSoftTrigger, // 人2
        CapPause  //3
    };
    OR_QML_STATE_PROPERTY(float , capfrequency, 0.0)
    OR_QML_STATE_PROPERTY(int , todayAllnum , 0);
    Q_INVOKABLE void resetTodayallNum();

    AUTO_SETTING_PROPERTY(ImageProcessor , QString,  linkName , "张小姐")
    AUTO_SETTING_PROPERTY(ImageProcessor , QString,  linkPhone, "180273314")
    AUTO_SETTING_PROPERTY(ImageProcessor , QString,  linkadd, "广东省东莞市长安镇沙头东大路28号503室")
    AUTO_SETTING_PROPERTY(ImageProcessor , QString,  linkComny, "东莞市匠铺智能设备有限公司")

    AUTO_SETTING_PROPERTY(ImageProcessor , int ,  discharge2cutting , 5) //出料口到切刀
    AUTO_SETTING_PROPERTY(ImageProcessor , float,  totalLength , 100)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",float, fabriclengthcm)

    Q_INVOKABLE void autoSettrimminginterval();

    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int, continuousComp)

    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,expectedFPS)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,Maxmultithreading)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,numberbatch)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,cachequantity)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,wasteToCutting)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,trimminginterval)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,removeBaseDuration)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,removeBaseDelay)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,plcStopDelay)

    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",QVariantList,iO1SignalReceived)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",QVariantList,iO2SignalReceived)

    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,inplaceShake)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int,inplaceDelay)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",bool,InplaceIsStop)

    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int ,InplaceModel)//1shebiao //guangdian
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int ,inplaceOverTimes)//cuoweiduoshaotingji

    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",float ,moveDistanceRed)//cuoweiduoshaotingji
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",bool ,moveDistanceEnable)//cuoweiduoshaotingji


    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int ,speedDiff)
    AUTO_CONFIG_PROPERTY(ImageProcessor,"base",int ,waste2outlet)
    //AUTO_CONFIG_PROPERTY(ImageProcessor,"base",bool , iscamearaAEWhite)

    OR_QML_STATE_PROPERTY(float, moveDistanceMin , 0)
    OR_QML_STATE_PROPERTY(float, moveDistanceMax , 0)
    OR_QML_STATE_PROPERTY(float, moveDistance , 0)
    OR_QML_STATE_PROPERTY(int, setFabricSpacingTime , 0)
    OR_QML_STATE_PROPERTY(int, setMoveDistanceime , 0)
    OR_QML_STATE_PROPERTY(int, distanceOvertime , 0)


    Q_INVOKABLE void shutdownSystem();
    Q_INVOKABLE void closeApplication();
    Q_INVOKABLE void closeService();

    Q_INVOKABLE void startAutoOperation();
    Q_INVOKABLE void stopAutoOperation();
    Q_INVOKABLE void autoContinueProcess();

    Q_INVOKABLE void startPLC();
    Q_INVOKABLE void stopPLC();
    Q_INVOKABLE void realTimestopPLC();

    ProcessingAbortMode getCurrentAbortMode() const {return currentAbortMode_;};
    void startTriggerLoop();
    void stopTriggerLoop();

    QVariantMap displayimageInfo() const { return displayimageInfo_;}
    float currentFrameRate() const { return currentFrameRate_;}

    MeauName selectedStep() const {return selectedStep_;};
    void setSelectedStep(MeauName selectedStep);

    // int maxFrameRate() const {return maxFrameRate_;};
    // void setmaxFrameRate(int maxFrameRate);

    void setdetectDetail(const QString context);
    QString detectDetail()const{return m_detectDetail;};


    bool detectIsOk()const {return m_detectIsOk;};
    void setdetectIsOk(bool detectIsOk);

    QString NgResonDetail()const {return m_NgResonDetail;};
    void setNgResonDetail(const QString NgResonDetail);

    void displayOKNGReson(const NgCard& ngCard);

    int multithreading() const{return multithreading_;};
    void setmultithreading(int multithreading);

    QVariantMap detectStepTime() const {return detectStepTime_;};
    void displaydetectStepTime(QVariantMap detectStepTime);

    QVariantMap detectStepInfo() const {return detectStepInfo_;};
    void displaydetectStepInfo(QVariantMap detectStepInfo);

    int imgDisplayDelay() const {return imgDisplayDelay_;};
    void displayDisplayDelay(int imgDisplayDelay);

    int photographyDelay() const {return photographyDelay_;};
    void setphotographyDelay(int photographyDelay);



    Q_INVOKABLE void setdisplayHistory(bool displayHistory);
    Q_INVOKABLE void setAbortMode(ProcessingAbortMode mode);
    // Q_INVOKABLE void setIdentifiROI(int x , int y ,int width ,int height);
    // Q_INVOKABLE void setMonitorROI(int x , int y ,int width ,int height);

    ImageProcessor::CaptureImgMode captureImgMode()const {return captureImgMode_;};
    void setcaptureImgMode(ImageProcessor::CaptureImgMode mode);


    Status totalStauts(){return state_;};

    static void *triggerLooptest(void *arg);
    void triggerLoop();

    void DetectFullProcess(ImageRecord &imageRecord);
    void multithreadingsub();
    void multithreadingAdd();
    void sendImgInfo(cv::Mat &frame);
    bool displayHistory_ = false;
    ImageRecord imgCardsLast;
public slots:
    void getFinishProcess(ImageRecord imgCard);
    void cameraStatusChanged();
    void valueTableLoad();

signals:
    void sudentStopContinue();// guanbi
    void inplaceSlidingStepSign(); //diu bu
    void monitorImgChange(cv::Mat& img);
    void identifiImgImgChange(cv::Mat& img);
    void currentFrameRateChanged();
    void displayimageInfoChanged();
    void statusChanged(ImageProcessor::Status newStatus);
    void processingError(const QString &error);
    void processingWarning(const QString &error);
    void captureImgModeChange();
    void selectedStepChange();
    void imgDisplayDelayChange();
    void detectDetailChanged();
    void detectIsOkChanged();
    void NgResonDetailChanged();
    void multithreadingChange();
    void detectStepTimeChange();
    void detectStepInfoChange();

    void photographyDelayChanged();
    void shortageGriggerSign();
    void inplaceSign();
    void arriveBatchGriggerSign();
    void logosizeChangeSign();

private slots:
    void onIO1SignalReceived();
    void onIO2SignalReceived();

private:
    ImageProcessor(ImageProvider *imageProvider, QObject *parent = nullptr);
    ~ImageProcessor();
    ImageProcessor(const ImageProcessor&) = delete;
    ImageProcessor& operator=(const ImageProcessor&) = delete;


    cv::Mat emphasePreprocess(cv::Mat image , bool isShowMain);
    //线程explicit FloorSetting(QObject *parent = nullptr);
    AutoRunProcess autoRunProcess;
    QThread autoRunProcessThread;
    //pthread_t nThreadID;
    //图片缓存
    cv::Mat monitorImg;
    cv::Mat identifiImg;

    //暴露变量
    QVariantMap displayimageInfo_;

    // 子模块
    CameraEth0 &camera_;
    ImageProvider *imageProvider_;
    QThreadPool *threadPool_;
    QThreadPool threadTriggerLoop;

    // 处理参数
    ProcessingAbortMode currentAbortMode_;
    CaptureImgMode captureImgMode_;
    Status state_;
    QString lastError_;
    // int maxFrameRate_;
    // int frameInterval_; // ms
    int maxRecords_;
    int processedFramesCount_;
    int multithreading_;
    StepProcess endStep_;
    MeauName selectedStep_;
    QString m_detectDetail;
    bool m_detectIsOk;
    QString m_NgResonDetail;
    QVariantMap dete;
    int photographyDelay_;
    QVariantMap detectStepInfo_;
    QVariantMap detectStepTime_;

    // 帧率计算
    QElapsedTimer elapsedTimer_;
    std::deque<qint64> frameTimestamps_;
    const size_t maxIntervals_ = 15; // 保持最近15帧的时间间隔
    float currentFrameRate_;
    int imgDisplayDelay_;
    // 图像缓存


    // 互斥锁
    int runningTaskCount_;
    std::mutex stateMutex_;
    std::mutex imageCardMutex_;
    std::mutex multithreadMutex_;
    QSemaphore CameeraSemaphore;
    QSemaphore pauseSemaphore_;
    //自动运行界面显示


    // 私有方法
    QImage convertToQImage(const cv::Mat &mat);

    void setStatus(Status newStatus);
    void updateFrameRate();
    
    //自动运行
    QTimer *debounceTimer = nullptr;
    QSettings setting;
};



#endif // IMAGEPROCESSOR_H
